package com.xiaoxu.intranetweb.mybatisplusSzappdb.business.truck;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xiaoxu.intranetweb.dom4jUtil.config.SystemConfigReader;
import com.xiaoxu.intranetweb.mybatisplusSzappdb.business.wxInform.WxInformBu;
import com.xiaoxu.intranetweb.mybatisplusSzappdb.entity.*;
import com.xiaoxu.intranetweb.mybatisplusSzappdb.mapper.COrderDetailMapper;
import com.xiaoxu.intranetweb.mybatisplusSzappdb.mapper.TTrucksOvertimeMapper;
import com.xiaoxu.intranetweb.mybatisplusSzappdb.service.*;
import com.xiaoxu.intranetweb.util.SzResult;
import groovyjarjarpicocli.CommandLine;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.print.DocFlavor;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@Slf4j
// 车辆排队信息处理类
public class TruckCallZxBu {
    @Autowired
    private ICTrucksUpdateService iCTrucksUpdateService;
    @Autowired
    private ICTrucksService iCTrucksService;
    @Autowired
    private ITSpecialPriceTypeService itSpecialPriceTypeService;
    @Autowired
    private ITSpecialPriceService itSpecialPriceService;
    @Autowired
    private ICCompanysService icCompanysService;
    @Autowired
    private ICPdtsAuthService iCPdtsAuthService;
    @Autowired
    private ICProductsInfoService icProductsInfoService;
    @Autowired
    private ICAshGateVideoBindService iCAshGateVideoBindService;
    @Autowired
    private WxInformBu wxInformBu;
    @Autowired
    private ICPdtClassService icPdtClassService;
    @Autowired
    private ICSysCfgService iCSysCfgService;
    @Autowired
    private ITGypsumPlanService iTGypsumPlanService;
    @Autowired
    private ITTrucksOvertimeService itTrucksOvertimeService;
    @Autowired
    private ISysDicService sysDicService;
    @Autowired
    private ICWeightSheetsService iCWeightSheetsService;
    @Autowired
    private ICPdtsAuthService icPdtsAuthService;
    @Autowired
    private ICOrderDetailService iCOrderDetailService;
    @Autowired
    private ICCompanysService iCCompanysService;
    @Autowired
    private COrderDetailMapper cOrderDetailMapper;
    @Autowired
    private ITAshGateCollocationService iTAshGateCollocationService;

    @Autowired
    private QueueHandlingZxBu queueHandlingZxBu;
    @Autowired
    private SystemConfigReader systemConfigReader;
    @Autowired
    private ITTrucksOvertimeRecordService iTTrucksOvertimeRecordService;
    @Autowired
    private TTrucksOvertimeMapper tTrucksOvertimeMapper;


    //    车辆排队CTrucksUpdate信息处理
    public void getTruckQueue() {
        QueryWrapper<CTrucksUpdate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("UPDATE_TYPE", 5);
        queryWrapper.like("HANDLED", 0);
        queryWrapper.eq("HANDLED_RESULT", 0);
        queryWrapper.eq("TRUCKS_DELETED", 0);
        queryWrapper.orderByAsc("HANDLED_TIME");
        List<CTrucksUpdate> list = iCTrucksUpdateService.list(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        for (int i = 0; i < list.size(); i++) {
//            先检查排的是什么品种
            String pdtId = list.get(i).getTrucksCheckinPdt();
//            排队车号
            String trucksNo = list.get(i).getTrucksTruckno();
//            排队时间HANDLED_TIME
            LocalDateTime checkinTime = list.get(i).getHandledTime();
//            排队单位
            String checkinCo = list.get(i).getTrucksCheckinCo();
//            装载点
            String loadsite = list.get(i).getTrucksCheckinLoadsite();
//            排队卡号
            String cardNo = "";
            if (list.get(i).getTrucksCheckinCardno() != null && !list.get(i).getTrucksCheckinCardno().equals("")) {
                cardNo = list.get(i).getTrucksCheckinCardno();
            }
            QueryWrapper<CTrucks> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("TRUCKS_TRUCKNO", trucksNo);
            wrapper2.eq("TRUCKS_DELETED", 0);
            CTrucks cTrucks3 = iCTrucksService.getOne(wrapper2);
            if (cTrucks3.getTrucksQueueStatus().compareTo(BigDecimal.valueOf(2))>=0){
                CTrucksUpdate cTrucksUpdate = new CTrucksUpdate();
                cTrucksUpdate.setId(list.get(i).getId());
                cTrucksUpdate.setHandled("22222222");
                cTrucksUpdate.setHandledResult(100);
                cTrucksUpdate.setHandledResultStr("回复：排队失败，此车可能已手动叫号或已经处在叫号以上状态");
                iCTrucksUpdateService.updateById(cTrucksUpdate);
                continue;
            }


//先處理排队信息
            CTrucksUpdate cTrucksUpdate = new CTrucksUpdate();
            cTrucksUpdate.setId(list.get(i).getId());
            cTrucksUpdate.setUpdateType(5);
            cTrucksUpdate.setHandled("22222222");
            cTrucksUpdate.setHandledResult(100);
            cTrucksUpdate.setHandledResultStr("回复：排队成功");
            Boolean flag = iCTrucksUpdateService.updateById(cTrucksUpdate);
//     写入车辆表完成排队
            if (flag) {
                QueryWrapper<CTrucks> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("TRUCKS_TRUCKNO", trucksNo);
                wrapper1.eq("TRUCKS_DELETED", 0);
                CTrucks cTrucks2 = iCTrucksService.getOne(wrapper1);
//                UpdateWrapper<CTrucks> updateWrapper = new UpdateWrapper<>();
//                updateWrapper.eq("TRUCKS_TRUCKNO", trucksNo);
//                updateWrapper.ne("TRUCKS_DELETED", 1);
//                updateWrapper
                CTrucks cTrucks1 = new CTrucks();
                //            车辆是否有vip排队特权
                if (cTrucks2.getTrucksQueueVip() !=null) {
                    cTrucks1.setTrucksQueueVip(cTrucks2.getTrucksQueueVip());
                }else {
                    cTrucks1.setTrucksQueueVip(0);
                }
                cTrucks1.setId(cTrucks2.getId());
                cTrucks1.setTrucksCheckinCo(checkinCo);
                cTrucks1.setTrucksQueueStatus(BigDecimal.valueOf(1));
                cTrucks1.setTrucksTruckno(trucksNo);
                cTrucks1.setTrucksCheckinPdt(pdtId);
                cTrucks1.setTrucksCheckinNo(BigDecimal.valueOf(0));
//                TRUCKS_CHECKIN_NO
//                cTrucks1.setTrucksCheckinNo(BigDecimal.valueOf(cTrucks.size()+1));
                cTrucks1.setTrucksCheckinTm(checkinTime);
                cTrucks1.setTrucksCheckinLoadsite(loadsite);
                if (cTrucks2.getTrucksRefNet() != null) {
                    cTrucks1.setTrucksPreDeduct(cTrucks2.getTrucksRefNet());
                } else {
                    cTrucks1.setTrucksPreDeduct(BigDecimal.valueOf(0));
                }
//                TRUCKS_CHECKIN_CARDNO,这里可以为空，因为为空的时候说明就是临时车
                if (cardNo != null && !cardNo.equals("")) {
                    cTrucks1.setTrucksCheckinCardno(cardNo);
                }
//                获取价格
//                todo 这里我要再想想如果是本地排队，我应该怎么处理这些数据，现在最必要的就是车辆回磅后要抹去他的排队信息，手机排队倒没关系，因为手机每次排队会更新他的数据
//                目前的解决方式是，当本地排队的时候，本地排队肯定是不拿车辆的竞价或者市场价信息的，那么pricetype就为空
                if (cTrucks2.getPriceType() == null || cTrucks2.getPriceType().equals("")) {
                    TSpecialPrice priceDetail = getPriceDetail(pdtId, checkinCo, checkinTime.toString());
                    if (priceDetail != null) {
//                    暂且写在排队的瞬间了(2024.8.05我又改回在处理排队信息时处理了，主要是上面判断了cTrucks2.getPriceType() == null
                    cTrucks1.setPriceId(priceDetail.getPriceTypeId());
                    cTrucks1.setSpecialPrice(priceDetail.getPrice());
                    cTrucks1.setPriceType(priceDetail.getPriceType());
//                    更新一下特殊价的剩余量,不用了，我现在直接在排队的时候就处理了
                    TSpecialPrice tSpecialPrice = new TSpecialPrice();
                    tSpecialPrice.setId(priceDetail.getId());
                    tSpecialPrice.setResidueNum(priceDetail.getResidueNum().subtract(BigDecimal.valueOf(1)));
                    itSpecialPriceService.updateById(tSpecialPrice);
                    }
//                没有竞价时拿市场价
                    else {
//                    CPdtsAuth cpdtsAuth = getMarketPrice(pdtId, checkinCo);
                        cTrucks1.setPriceId("100db760390111ef987900ff8a757bed");
                        cTrucks1.setSpecialPrice(BigDecimal.valueOf(0));
                        cTrucks1.setPriceType("市场价");
                    }
                }
                iCTrucksService.updateById(cTrucks1);
            }
        }
    }

    //    还得找粉煤灰的竞价信息、石膏的竞价信息、石膏渣的计划的价格数据
    public TSpecialPrice getPriceDetail(String pdtId, String coId, String checkinTm) {
        List<TSpecialPrice> list = fetchSpecialPrices(pdtId, coId, checkinTm);
        List<TSpecialPriceType> list1 = itSpecialPriceTypeService.list();

        // Filter out TSpecialPriceType where enableFlag is 0 before creating the map
        List<TSpecialPriceType> filteredList1 = list1.stream()
                .filter(priceType -> priceType.getEnableFlag() != 0)
                .collect(Collectors.toList());

        Map<String, TSpecialPriceType> priceTypeMap = filteredList1.stream()
                .collect(Collectors.toMap(TSpecialPriceType::getId, priceType -> priceType));

        // Filter TSpecialPrice objects based on the enableFlag of their associated TSpecialPriceType
        List<TSpecialPrice> filteredList = list.stream()
                .filter(sp -> priceTypeMap.containsKey(sp.getPriceTypeId()) && priceTypeMap.get(sp.getPriceTypeId()).getEnableFlag() != 0)
                .sorted(Comparator.comparing((TSpecialPrice sp) -> priceTypeMap.get(sp.getPriceTypeId()).getPriceSort())
                        .thenComparing(TSpecialPrice::getPrice))
                .collect(Collectors.toList());

        LinkedList<TSpecialPrice> linkedList = new LinkedList<>(filteredList);
        return linkedList.isEmpty() ? null : linkedList.get(0);
    }




    //拿到还有余量的定价数据
    private List<TSpecialPrice> fetchSpecialPrices(String pdtId, String coId, String checkinTm) {
        QueryWrapper<TSpecialPrice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PDT_ID", pdtId)
                .eq("CO_ID", coId)
                .le("START_TIME", checkinTm)
                .ge("END_TIME", checkinTm)
                .gt("RESIDUE_NUM", 0);
        return itSpecialPriceService.list(queryWrapper); // Assuming iTSpecialPriceService is an injected service
    }

    public TSpecialPrice getPriceDetail1(String pdtId, String coId, String checkinTm,String priceId) {
        List<TSpecialPrice> list = fetchSpecialPrices1(pdtId, coId, checkinTm,priceId);
        List<TSpecialPriceType> list1 = itSpecialPriceTypeService.list();

        // Filter out TSpecialPriceType where enableFlag is 0 before creating the map
        List<TSpecialPriceType> filteredList1 = list1.stream()
                .filter(priceType -> priceType.getEnableFlag() != 0)
                .collect(Collectors.toList());

        Map<String, TSpecialPriceType> priceTypeMap = filteredList1.stream()
                .collect(Collectors.toMap(TSpecialPriceType::getId, priceType -> priceType));

        // Filter TSpecialPrice objects based on the enableFlag of their associated TSpecialPriceType
        List<TSpecialPrice> filteredList = list.stream()
                .filter(sp -> priceTypeMap.containsKey(sp.getPriceTypeId()) && priceTypeMap.get(sp.getPriceTypeId()).getEnableFlag() != 0)
                .sorted(Comparator.comparing((TSpecialPrice sp) -> priceTypeMap.get(sp.getPriceTypeId()).getPriceSort())
                        .thenComparing(TSpecialPrice::getPrice))
                .collect(Collectors.toList());

        LinkedList<TSpecialPrice> linkedList = new LinkedList<>(filteredList);
        return linkedList.isEmpty() ? null : linkedList.get(0);
    }
    private List<TSpecialPrice> fetchSpecialPrices1(String pdtId, String coId, String checkinTm,String priceId) {
        QueryWrapper<TSpecialPrice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PDT_ID", pdtId)
                .eq("CO_ID", coId)
                .eq("PRICE_TYPE_ID", priceId)
                .le("START_TIME", checkinTm)
                .ge("END_TIME", checkinTm);
//                .gt("RESIDUE_NUM", 0);
        return itSpecialPriceService.list(queryWrapper); // Assuming iTSpecialPriceService is an injected service
    }
    //拿到市场价
//    public CPdtsAuth getMarketPrice(String pdtId, String coId) {
//        QueryWrapper<CCompanys> queryWrapper1 = new QueryWrapper<>();
//        queryWrapper1.eq("ID", coId);
//        CCompanys cCompanys = icCompanysService.getOne(queryWrapper1);
//        QueryWrapper<CPdtsAuth> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("PDTSAUTH_PDT", pdtId);
//        queryWrapper.eq("PDTSAUTH_CO", cCompanys.getCpyCo());
//        queryWrapper.eq("PDTSAUTH_CHICO", cCompanys.getCpyChico());
//        queryWrapper.ne("PDTSAUTH_DELETED", 1);
//        return iCPdtsAuthService.getOne(queryWrapper);
//    }


    //==================执行叫号逻辑============================
    public void  getTruckCallZx() {
        LocalDateTime callInTM = LocalDateTime.now();
        QueryWrapper<CTrucks> cTrucksQueryWrapper = new QueryWrapper<>();
//        查询正在等待的车
        cTrucksQueryWrapper.eq("TRUCKS_QUEUE_STATUS", 1);
        cTrucksQueryWrapper.eq("TRUCKS_DELETED", 0);
        cTrucksQueryWrapper.isNotNull("TRUCKS_CHECKIN_PDT");
        cTrucksQueryWrapper.isNotNull("TRUCKS_CHECKIN_TM");
        cTrucksQueryWrapper.isNotNull("TRUCKS_CHECKIN_NO");
//        cTrucksQueryWrapper.orderByAsc("TRUCKS_CHECKIN_TM");
        cTrucksQueryWrapper.orderByAsc("TRUCKS_CHECKIN_NO");
        List<CTrucks> cTrucks = iCTrucksService.list(cTrucksQueryWrapper);
        LinkedList<CTrucks> sortedCTrucks = cTrucks.stream()
                .sorted(Comparator.comparing(CTrucks::getTrucksCheckinNo)
                        .thenComparing(CTrucks::getTrucksCheckinTm))
                .collect(Collectors.toCollection(LinkedList::new));
        if (cTrucks.size() == 0) {
            return;
        }
//       循环所有没叫号的车
        for (int i = 0; i < sortedCTrucks.size(); i++) {
//            拿到车辆排队的品种
            String pdtId = sortedCTrucks.get(i).getTrucksCheckinPdt();
            String plantId = sortedCTrucks.get(i).getDataFrom();
//            根据品种查出装载点
            QueryWrapper<CProductsInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("ID", pdtId);
            wrapper.eq("PDTINF_DELETED", 0);
            CProductsInfo cProductsInfo = icProductsInfoService.getOne(wrapper);
            QueryWrapper<CCompanys> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("ID", sortedCTrucks.get(i).getTrucksCheckinCo());
            CCompanys cCompanys = icCompanysService.getOne(wrapper1);
            QueryWrapper<CPdtClass> pdtClasswrapper = new QueryWrapper<>();
            pdtClasswrapper.eq("ID", cProductsInfo.getPdtinfClass());
            CPdtClass cPdtClass = icPdtClassService.getOne(pdtClasswrapper);
//            这里判断一下是否在石膏叫号的时间范围内，在石膏叫号的时间范围内就给石膏叫号
//            if (cPdtClass.getId().equals("2")) {
//                QueryWrapper<SysDic> queryWrapper = new QueryWrapper<>();
//                queryWrapper.eq("DIC_KEY", "truck_call_start_shigao");
//                queryWrapper.eq("DATA_FROM", plantId);
//                SysDic sysDic = sysDicService.getOne(queryWrapper);
//                QueryWrapper<SysDic> queryWrapper1 = new QueryWrapper<>();
//                queryWrapper1.eq("DIC_KEY", "truck_call_stop_shigao");
//                queryWrapper1.eq("DATA_FROM", plantId);
//                SysDic sysDic1 = sysDicService.getOne(queryWrapper1);
//                if (sysDic != null && sysDic1 != null) {
//                    String startTimeStr = sysDic.getDicVal();
//                    String endTimeStr = sysDic1.getDicVal();
//                    LocalTime startTime = LocalTime.parse(startTimeStr, DateTimeFormatter.ofPattern("HH:mm"));
//                    LocalTime endTime = LocalTime.parse(endTimeStr, DateTimeFormatter.ofPattern("HH:mm"));
//                    LocalTime now = LocalTime.now();
//                    if (now.isBefore(startTime) || now.isAfter(endTime)) {
//                        continue;
//                    }
//                }
//            }

//            如果品种里面没有装载点就叫下一个车
            if (cProductsInfo.getPdtinfSpeSitelist() == null || cProductsInfo.getPdtinfSpeSitelist().equals("")) {
                continue;
            }
//          拿到装载点数据，cProductsInfo里的speloadsitepdtList使用id,id,id
//            String[] speloadsitepdtList = cProductsInfo.getPdtinfSpeSitelist().split(",");
////            speloadsitepdtList转成list
//            List<String> list = Arrays.asList(speloadsitepdtList);
////            查询单位绑定了哪些装载点
////            if (cCompanys.getLoadSite() == null || cCompanys.getLoadSite().equals("")) {
////                continue;
////            }
////            查到所有装载点
//            String[] loadSite = cCompanys.getLoadSite().split(",");
//            //            从装载点表拿到所有装载点
//            List<CAshGateVideoBind> intersection = new ArrayList<>();
//            for (String s : loadSite) {
//                QueryWrapper<CAshGateVideoBind> wrapper2 = new QueryWrapper<>();
//                wrapper2.eq("ID", s);
//                CAshGateVideoBind cAshGateVideoBind = iCAshGateVideoBindService.getOne(wrapper2);
//                intersection.add(cAshGateVideoBind);
//            }
//            下面找到对应公司绑定的装载点
// 转换list为Set以提高查找效率
//            Set<String> set = new HashSet<>(list);
//// 创建一个新列表用于存储匹配的CAshGateVideoBind对象
//            List<CAshGateVideoBind> matchedIntersection = new ArrayList<>();
//// 遍历intersection，检查ashgateName是否在set中
//            for (CAshGateVideoBind bind : intersection) {
//                if (set.contains(bind.getAshgateName())) {
//                    matchedIntersection.add(bind);
//                }
//            }
            //                    拿到品种的装载点

//            当一条装载点都匹配不到的话就继续处理其他车
//            if (matchedIntersection.size() == 0) {
//                    continue;
//            }
//            for (CAshGateVideoBind ashGateVideoBind : matchedIntersection) {
//                for (CAshGateVideoBind ashGateVideoBind : intersection) {
            if (cProductsInfo.getPdtinfStockcls()==0) {
                if (sortedCTrucks.get(i).getTrucksCheckinLoadsite() ==null){
                    continue;
                }
                QueryWrapper<CAshGateVideoBind> wrapper2 = new QueryWrapper<>();
                wrapper2.eq("ASHGATE_NAME", sortedCTrucks.get(i).getTrucksCheckinLoadsite());
                wrapper2.eq("ASHGATE_DELETED", 0);
                wrapper2.eq("DATA_FROM", plantId);
                CAshGateVideoBind ashGateVideoBind = iCAshGateVideoBindService.getOne(wrapper2);
                if (ashGateVideoBind == null) {
                    continue;
                }
                QueryWrapper<CTrucks> cTrucksQueryWrapper1 = new QueryWrapper<>();
                cTrucksQueryWrapper1.ge("TRUCKS_QUEUE_STATUS", 2);
                cTrucksQueryWrapper1.le("TRUCKS_QUEUE_STATUS", 6);
                cTrucksQueryWrapper1.eq("TRUCKS_DELETED", 0);
                cTrucksQueryWrapper1.eq("TRUCKS_CHECKIN_LOADSITE", ashGateVideoBind.getAshgateName());
                cTrucksQueryWrapper1.isNotNull("TRUCKS_CHECKIN_TM");
                cTrucksQueryWrapper1.orderByAsc("TRUCKS_CHECKIN_TM");
                List<CTrucks> cTrucks1 = iCTrucksService.list(cTrucksQueryWrapper1);
                // 拿到库容量
                Integer vehicleCapacity = ashGateVideoBind.getVehicleCapacity();
                // 如果cTrucks1不为空，那就判断，库容量是否够，如果为空就执行这个库
                if (cTrucks1.size() < vehicleCapacity) {
                    CTrucks cTrucks2 = new CTrucks();
//                进门是0
                    cTrucks2.setTrucksEntered(0);
//                    叫号
                    cTrucks2.setTrucksQueueStatus(BigDecimal.valueOf(2));
//                    cTrucks2.setTrucksCheckinLoadsite(ashGateVideoBind.getAshgateName());
                    cTrucks2.setTrucksCheckinLoadsiteAdd(getSellMethod(ashGateVideoBind.getId()));
                    cTrucks2.setSupplyCoId(ashGateVideoBind.getAshgateSubjectId());
                    cTrucks2.setTrucksCallinTm(callInTM);
                    cTrucks2.setTrucksEnterTm(null);
                    cTrucks2.setTrucksEntered(0);
                    cTrucks2.setTrucksCheckinLoadsiteSn(ashGateVideoBind.getAshgateSn());
                    UpdateWrapper<CTrucks> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("ID", sortedCTrucks.get(i).getId());
                    iCTrucksService.update(cTrucks2, updateWrapper);
//                    执行微信推送叫号
                    wxInformBu.wxTruckInformFeign(sortedCTrucks.get(i));

//                    如果这个车叫号成功了就跳出这个分配库的循环，以免叫到其他库去了
//                    break;
                }
            }else {
                CTrucks cTrucks2 = new CTrucks();

//                进门是0
                cTrucks2.setTrucksEntered(0);
//                    叫号
                cTrucks2.setTrucksQueueStatus(BigDecimal.valueOf(2));
//                    cTrucks2.setTrucksCheckinLoadsite(ashGateVideoBind.getAshgateName());
//                cTrucks2.setTrucksCheckinLoadsiteAdd(getSellMethod(ashGateVideoBind.getId()));
//                cTrucks2.setSupplyCoId(ashGateVideoBind.getAshgateSubjectId());
                cTrucks2.setTrucksCallinTm(callInTM);
                cTrucks2.setTrucksEnterTm(null);
                cTrucks2.setTrucksEntered(0);
//                cTrucks2.setTrucksCheckinLoadsiteSn(ashGateVideoBind.getAshgateSn());
                UpdateWrapper<CTrucks> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("ID", sortedCTrucks.get(i).getId());
                iCTrucksService.update(cTrucks2, updateWrapper);
//                    执行微信推送叫号
                wxInformBu.wxTruckInformFeign(sortedCTrucks.get(i));

            }
            }
        }
//    }

    //    这是一个公共方法用来处理车辆叫排队序号
//    加个1分钟执行一次的定时器
//@Scheduled(cron = "0 0/1 * * * ?")
    public void updateTruckQueueNo() {
        QueryWrapper<CTrucks> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("TRUCKS_QUEUE_STATUS", 0);
        queryWrapper.eq("TRUCKS_DELETED", 0);
        queryWrapper.isNotNull("TRUCKS_CHECKIN_PDT");
        queryWrapper.isNotNull("TRUCKS_CHECKIN_TM");
        List<CTrucks> cTrucks = iCTrucksService.list(queryWrapper);
        // 使用 LinkedHashMap 来保持分组的插入顺序
        Map<String, List<CTrucks>> groupedAndSorted = cTrucks.stream()
                .collect(Collectors.groupingBy(
                        CTrucks::getTrucksCheckinPdt,
                        LinkedHashMap::new,
                        Collectors.toList()));

        // 遍历每个分组，并在每个组内按 trucksCheckinTM 排序
        groupedAndSorted.forEach((pdt, trucks) -> {
                    // 先将卡车按照是否 VIP 分类
                    List<CTrucks> vipTrucks = trucks.stream()
                            .filter(truck -> truck.getTrucksQueueVip() == 1)
                            .sorted(Comparator.comparing((CTrucks truck) -> {
                                        String priceId = truck.getPriceId();
                                        // 如果 priceId 为空或者为空字符串，则返回 1，表示较低的优先级
                                        if (priceId == null || priceId.isEmpty()) {
                                            return 1;
                                        }
                                        // 如果 priceId 等于特定市场价 ID，则返回 0，表示较高的优先级
                                        return priceId.equals("100db760390111ef987900ff8a757bed") ? 0 : 1;
                                    })
                                    .thenComparing(Comparator.comparing(CTrucks::getSpecialPrice, Comparator.nullsFirst(Comparator.reverseOrder())))
                                    .thenComparing(CTrucks::getTrucksCheckinTm))
                            .collect(Collectors.toList());

                    List<CTrucks> nonVipTrucks = trucks.stream()
                            .filter(truck -> truck.getTrucksQueueVip() != 1)
                            .sorted(Comparator.comparing((CTrucks truck) -> {
                                        String priceId = truck.getPriceId();
                                        // 如果 priceId 为空或者为空字符串，则返回 1，表示较低的优先级
                                        if (priceId == null || priceId.isEmpty()) {
                                            return 1;
                                        }
                                        // 如果 priceId 等于特定市场价 ID，则返回 0，表示较高的优先级
                                        return priceId.equals("100db760390111ef987900ff8a757bed") ? 0 : 1;
                                    })
                                    .thenComparing(Comparator.comparing(CTrucks::getSpecialPrice, Comparator.nullsFirst(Comparator.reverseOrder())))
                                    .thenComparing(CTrucks::getTrucksCheckinTm))
                            .collect(Collectors.toList());


            // 合并两个列表
            List<CTrucks> allTrucks = Stream.concat(vipTrucks.stream(), nonVipTrucks.stream())
                    .collect(Collectors.toList());
            // 给每个卡车分配一个检查编号
            int queueNo = 1;
            List<CTrucks> allTrucksForUpdate = new ArrayList<>();
            for (CTrucks truck : allTrucks) {
                truck.setId(truck.getId());
                truck.setTrucksId(truck.getTrucksId());
                truck.setTrucksCheckinNo(BigDecimal.valueOf(queueNo++));
                allTrucksForUpdate.add(truck);
            }
            // 使用 MyBatis Plus 的批量更新方法
            iCTrucksService.updateBatchById(allTrucksForUpdate);
          }
        );
    }

    //    处理叫号超时的车辆
    public void handleTimeoutTrucks() {
        //        查询什么时候不执行叫号超时
        QueryWrapper<SysDic> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("DIC_KEY", "queueControl_stop_overtime_start");
        SysDic sysDic1 = sysDicService.getOne(queryWrapper3);
        QueryWrapper<SysDic> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("DIC_KEY", "queueControl_stop_overtime_end");
        SysDic sysDic2 = sysDicService.getOne(queryWrapper2);
        LocalTime startTime = LocalTime.parse(sysDic1.getDicVal(), DateTimeFormatter.ofPattern("HH:mm"));
        LocalTime endTime = LocalTime.parse(sysDic2.getDicVal(), DateTimeFormatter.ofPattern("HH:mm"));
        LocalTime now1 = LocalTime.now();
        if (now1.isAfter(startTime) && now1.isBefore(endTime)) {
            return;
        }
        QueryWrapper<CTrucks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("TRUCKS_QUEUE_STATUS", 2);
        queryWrapper.eq("TRUCKS_DELETED", 0);
        queryWrapper.isNotNull("TRUCKS_CHECKIN_PDT");
        queryWrapper.isNotNull("TRUCKS_CHECKIN_TM");
        queryWrapper.orderByAsc("TRUCKS_CALLIN_TM");
        List<CTrucks> cTrucks = iCTrucksService.list(queryWrapper);
        if (cTrucks.size() == 0) {
            return;
        }

        for (CTrucks cTrucks1 : cTrucks) {

//如果生成单子了就不要给他超时了
            LocalDateTime callTm = cTrucks1.getTrucksCallinTm();
            LocalDateTime now = LocalDateTime.now();
            long minutes = ChronoUnit.MINUTES.between(callTm, now);
//            先定义一个过号时间
            long timeoutMinutes = 120;
//            在配置文件里找到超时时间
//            先根据品种找到对应的品种类型
            QueryWrapper<CProductsInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("ID", cTrucks1.getTrucksCheckinPdt());
            CProductsInfo cProductsInfo = icProductsInfoService.getOne(wrapper);
            QueryWrapper<CPdtClass> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("ID", cProductsInfo.getPdtinfClass());
            CPdtClass cPdtClass = icPdtClassService.getOne(wrapper1);
            if (cPdtClass !=null) {
                if (cPdtClass.getId().equals("1")) {
                    QueryWrapper<CSysCfg> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("SYSCFG_ITEM_NAME", "QUCallInToPoundInTmLimitAsh");
                    wrapper2.eq("DATA_FROM", cTrucks1.getDataFrom());
                    CSysCfg cSysCfg = iCSysCfgService.getOne(wrapper2);
                    timeoutMinutes = Long.parseLong(String.valueOf(cSysCfg.getSyscfgLongValue()));
                } else if (cPdtClass.getId().equals("2")) {
                    QueryWrapper<CSysCfg> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("SYSCFG_ITEM_NAME", "QUCallInToPoundInTmLimitGypsum");
                    wrapper2.eq("DATA_FROM", cTrucks1.getDataFrom());
                    CSysCfg cSysCfg = iCSysCfgService.getOne(wrapper2);
                    timeoutMinutes = Long.parseLong(String.valueOf(cSysCfg.getSyscfgLongValue()));
                } else if (cPdtClass.getId().equals("3") || cPdtClass.getId().equals("a45ed1623ea342cc8544f8db17eff1fb")) {
                    QueryWrapper<CSysCfg> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("SYSCFG_ITEM_NAME", "QUCallInToPoundInTmLimitCinder");
                    wrapper2.eq("DATA_FROM", cTrucks1.getDataFrom());
                    CSysCfg cSysCfg = iCSysCfgService.getOne(wrapper2);
                    timeoutMinutes = Long.parseLong(String.valueOf(cSysCfg.getSyscfgLongValue()));
                } else {
                    QueryWrapper<CSysCfg> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("SYSCFG_ITEM_NAME", "QUCallInToPoundInTmLimit");
                    wrapper2.eq("DATA_FROM", cTrucks1.getDataFrom());
                    CSysCfg cSysCfg = iCSysCfgService.getOne(wrapper2);
                    timeoutMinutes = Long.parseLong(String.valueOf(cSysCfg.getSyscfgLongValue()));
                }
            }
//            //            如果是即将超时了，提前10分钟就再通知一次
//            if (minutes == timeoutMinutes - 10) {
//                wxInformBu.wxTruckInformFeign(cTrucks1);
//            }
//            如果是超过时间了，就踢出厂
            if (minutes > timeoutMinutes) {
                //          如果这个车子生成单子了，就不要超时了
                QueryWrapper<CWeightSheets> cWeightSheetsQueryWrapper = new QueryWrapper<>();
//            首先车号要匹配
                cWeightSheetsQueryWrapper.eq("WEISHT_TRUCKNO", cTrucks1.getTrucksTruckno());
//            要没出门的WEISHT_OUT_TM是null
                cWeightSheetsQueryWrapper.isNull("WEISHT_FULL_TM");
//            WEISHT_EMPTY_TM空车时间肯定在车辆的排队时间TRUCKS_CHECKIN_TM之后
                cWeightSheetsQueryWrapper.ge("WEISHT_EMPTY_TM",cTrucks1.getTrucksCheckinTm());
                cWeightSheetsQueryWrapper.eq("WEISHT_BACKED",0);
//没有被删除
                cWeightSheetsQueryWrapper.eq("WEISHT_DELETED",0);
                cWeightSheetsQueryWrapper.orderByDesc("WEISHT_EMPTY_TM");

                List<CWeightSheets> cWeightSheets = iCWeightSheetsService.list(cWeightSheetsQueryWrapper);
                if (cWeightSheets.size() > 0) {
                    continue;
                }
                wxInformBu.wxTruckOutInformFeign(cTrucks1);

//                记录进叫号超时表t_trucks_overtime
                TTrucksOvertime tTrucksOvertime = new TTrucksOvertime();
                tTrucksOvertime.setTruckId(cTrucks1.getId());
                tTrucksOvertime.setPdtId(cTrucks1.getTrucksCheckinPdt());
                tTrucksOvertime.setCheckinTime(cTrucks1.getTrucksCheckinTm());
                tTrucksOvertime.setCallTime(cTrucks1.getTrucksCallinTm());
                tTrucksOvertime.setCoId(cTrucks1.getTrucksCheckinCo());
                tTrucksOvertime.setOverTime(now);
                tTrucksOvertime.setTruckNo(cTrucks1.getTrucksTruckno());
//                itTrucksOvertimeService.save(tTrucksOvertime);
                tTrucksOvertimeMapper.insert(tTrucksOvertime);
                String overtimeId = tTrucksOvertime.getId();
//                更新车辆数据之前，先记录
                mapAndSaveToOvertimeRecord(cTrucks1,overtimeId);
                cTrucks1.setTrucksQueueStatus(BigDecimal.valueOf(0));
                cTrucks1.setTrucksQueueVip(0);
                cTrucks1.setTrucksCheckinNo(null);
                cTrucks1.setTrucksCallinTm(null);
                cTrucks1.setTrucksCheckinTm(null);
                cTrucks1.setTrucksCheckinPdt("");
                cTrucks1.setTrucksCheckinCo("");
                cTrucks1.setTrucksCheckinLoadsite("");
                cTrucks1.setTrucksCheckinLoadsiteSn(null);
                cTrucks1.setTrucksCheckinCardno("");
                cTrucks1.setTrucksCheckinLoadsiteAdd("");
                cTrucks1.setSupplyCoId("");
                iCTrucksService.updateById(cTrucks1);

            }
        }



    }


    /**
     * 将 CTrucks 数据映射到 TTrucksOvertimeRecord 并保存到数据库
     * @param cTrucks 源数据
     */
    public void mapAndSaveToOvertimeRecord(CTrucks cTrucks,String connId) {
        TTrucksOvertimeRecord tTrucksOvertimeRecord = new TTrucksOvertimeRecord();

        // 使用 BeanUtils 复制属性
        BeanUtils.copyProperties(cTrucks, tTrucksOvertimeRecord);
        String uuid = UUID.randomUUID().toString().replace("-", "");
        tTrucksOvertimeRecord.setId(uuid);
        // 特殊处理需要转换的字段
        tTrucksOvertimeRecord.setTrucksUuid(cTrucks.getId());
        tTrucksOvertimeRecord.setConnId(connId); // 假设 connId 就是 cTrucks 的 id

        // 保存到数据库
        iTTrucksOvertimeRecordService.save(tTrucksOvertimeRecord);
    }

    //            这里还要判断21.大袋灰、加湿灰、储备库炉渣（每天23:50:00直接就全部给他超时）
    public void handleTimeoutTrucks2() {
        LocalDateTime now = LocalDateTime.now();
        QueryWrapper<CTrucks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("TRUCKS_QUEUE_STATUS", 1);
        queryWrapper.ne("TRUCKS_DELETED", 1);
        queryWrapper.isNotNull("TRUCKS_CHECKIN_PDT");
        queryWrapper.isNotNull("TRUCKS_CHECKIN_TM");
        queryWrapper.orderByAsc("TRUCKS_CALLIN_TM");
        List<CTrucks> cTrucks = iCTrucksService.list(queryWrapper);
        if (cTrucks.size() == 0) {
            return;
        }
        for (CTrucks cTrucks1 : cTrucks) {
//            如果车辆排的是大袋灰、加湿灰、储备库炉渣（每天23:50:00直接就全部给他超时）
            if (cTrucks1.getTrucksCheckinPdt().equals("56260577b0ab4b5d9b84d9577fcac1d0")//大袋灰
                    || cTrucks1.getTrucksCheckinPdt().equals("b9da511ff1dd4969a0e9ce0dbeeb91c9")//加湿灰
                    || cTrucks1.getTrucksCheckinPdt().equals("c9cf42874ddc446891ec936c5bf67386")//储备库炉渣
            ) {
                cTrucks1.setTrucksQueueStatus(BigDecimal.valueOf(0));
                UpdateWrapper<CTrucks> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("ID", cTrucks1.getId());
                iCTrucksService.update(cTrucks1, updateWrapper);
                wxInformBu.wxTruckOutInformFeign(cTrucks1);
                TTrucksOvertime tTrucksOvertime = new TTrucksOvertime();
                tTrucksOvertime.setTruckId(cTrucks1.getId());
                tTrucksOvertime.setPdtId(cTrucks1.getTrucksCheckinPdt());
                tTrucksOvertime.setCallTime(cTrucks1.getTrucksCallinTm());
                tTrucksOvertime.setCoId(cTrucks1.getTrucksCheckinCo());
                tTrucksOvertime.setOverTime(now);
                tTrucksOvertime.setTruckNo(cTrucks1.getTrucksTruckno());
                itTrucksOvertimeService.save(tTrucksOvertime);
            }
        }
    }

    //    执行扣款
//    事务
    @Transactional
    public void startExecuteDeduction() {
        QueryWrapper<CWeightSheets> queryWrapper = new QueryWrapper<>();
        //有回磅时间
        queryWrapper.isNotNull("WEISHT_FULL_TM");
        //已经回磅
        queryWrapper.eq("WEISHT_BACKED", 1);
        //没有被删
        queryWrapper.eq("WEISHT_DELETED", 0);
        //没有完成扣款
        queryWrapper.and(i -> i.ne("WEISHT_DEDUCTION", 1).or().isNull("WEISHT_DEDUCTION"));
        List<CWeightSheets> cWeightSheets = iCWeightSheetsService.list(queryWrapper);
        for (int i = 0; i < cWeightSheets.size(); i++) {
            CWeightSheets cWeightSheets2 = cWeightSheets.get(i);
            QueryWrapper<CProductsInfo> productsInfQueryWrapper = new QueryWrapper<>();
            productsInfQueryWrapper.eq("PDTINF_PDT", cWeightSheets2.getWeishtProduct());
            productsInfQueryWrapper.eq("PDTINF_DELETED",0);
            CProductsInfo productsInfoInit = icProductsInfoService.getOne(productsInfQueryWrapper);

            QueryWrapper<CCompanys> companysInitQueryWrapper = new QueryWrapper<>();
            companysInitQueryWrapper.eq("CPY_DELETED", 0);
            companysInitQueryWrapper.eq("CPY_CO",cWeightSheets2.getWeishtCo());
            companysInitQueryWrapper.eq("CPY_CHICO",cWeightSheets2.getWeishtChiCo());
            CCompanys cCompanysInit = iCCompanysService.getOne(companysInitQueryWrapper);
            //        扣多少钱
            BigDecimal monery = new BigDecimal(0);
//        扣款的价格
            BigDecimal price = new BigDecimal(0);
            QueryWrapper<CProductsInfo> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("PDTINF_PDT",cWeightSheets2.getWeishtProduct());
            queryWrapper1.eq("PDTINF_DELETED", 0);
            CProductsInfo cProductsInfo = icProductsInfoService.getOne(queryWrapper1);
//        判断品种是否为出货类，如果是进货类就不扣款
            if (cProductsInfo.getPdtinfStockcls() == 1) {
                CWeightSheets cWeightSheets1 = new CWeightSheets();
                cWeightSheets1.setWeishtDeduction(BigDecimal.valueOf(1));
                UpdateWrapper<CWeightSheets> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("ID", cWeightSheets2.getId());
                iCWeightSheetsService.update(cWeightSheets1, updateWrapper);
            } else {

                //            拿到定价
                BigDecimal specialPrice = new BigDecimal(0);
                if (cWeightSheets2.getWeightSpecialPrice() != null) {
                    specialPrice = cWeightSheets2.getWeightSpecialPrice();
                }
//                如果遇到不是市场价,但是cWeightSheets2.getWeightSpecialPrice()是0.00或者空的情况,重新拿一次定价
                if (specialPrice.compareTo(BigDecimal.valueOf(0)) == 0 && !cWeightSheets2.getWeishtPriceId().equals("100db760390111ef987900ff8a757bed")) {
//                    getPriceDetail
//                        public TSpecialPrice getPriceDetail(String pdtId, String coId, String checkinTm) {
                    TSpecialPrice priceDetailMap = getPriceDetail1(productsInfoInit.getId(), cCompanysInit.getId(), cWeightSheets2.getWeishtCheckinTm().toString(),cWeightSheets2.getWeishtPriceId());
                    if (priceDetailMap != null) {
                        if (priceDetailMap.getPrice() != null) {
                            specialPrice = priceDetailMap.getPrice();
                        }
                    }else {
                        log.error("单号【" +cWeightSheets2.getWeishtSheetno() + "】" + "扣款失败，未找到定价信息");
                        continue;
                    }
                }
//            拿到市场价
                Map<String, Object> marketPriceMap = getPrice(cWeightSheets2.getWeishtProduct(), cWeightSheets2.getWeishtCo(),cWeightSheets2.getWeishtChiCo(),cWeightSheets2.getWeishtFullTm(),cWeightSheets2.getDataFrom());
                BigDecimal marketPrice = new BigDecimal(0);
                if (marketPriceMap.get("code").equals("1")) {
                    log.error("单号【" +cWeightSheets2.getWeishtSheetno() + "】" + "扣款失败，未找到品种授权信息的市场价");
                    continue;
                } else if (marketPriceMap.get("code").equals("2")) {
//                市场价为空，这时候市场价就为0
                    marketPrice = BigDecimal.valueOf(0);
                    continue;
                } else {
//                正常拿到市场价
                    marketPrice = new BigDecimal(marketPriceMap.get("price").toString());
                }
                getSellMethod1(cWeightSheets2,cWeightSheets2.getWeishtProduct(),cWeightSheets2.getDataFrom(),cWeightSheets2.getWeishtFullTm());
//                石膏根据计划扣公司的钱还是电厂的钱,在排队的时候就确定了，所以不考虑装载点，直接拿磅单里的供货单位作为收款单位即可
//                还要考虑带回装载点的品种
                if (cWeightSheets2.getWeishtCoSupply() != null && !cWeightSheets2.getWeishtCoSupply().equals("")

                ) {

//                    拿到发货单位
                    QueryWrapper<CCompanys> queryWrapper2 = new QueryWrapper<>();
                    queryWrapper2.eq("CPY_CO", cWeightSheets2.getWeishtCoSupply());
                    queryWrapper2.eq("CPY_CHICO", cWeightSheets2.getWeishtCoSupplyChi());
                    queryWrapper2.eq("DATA_FROM", cWeightSheets2.getDataFrom());
                    queryWrapper2.eq("CPY_DELETED", 0);
                    CCompanys cCompanys = iCCompanysService.getOne(queryWrapper2);
//                    那就开始扣款
                    if (cCompanys != null) {
//                        价格为市场价加上定价
                        price = marketPrice.add(specialPrice);
//拿到净重
                        BigDecimal netWeight = cWeightSheets2.getWeishtNetWght();
                        if (netWeight == null) {
                            netWeight = BigDecimal.ZERO;
                        }
                        monery = price.multiply(netWeight).setScale(2, RoundingMode.HALF_UP);

                        if (monery.compareTo(BigDecimal.ZERO) < 0) {
                            log.error("单号【" + cWeightSheets2.getWeishtSheetno() + "】" + "扣款失败，金额小于0");
                            CWeightSheets cWeightSheets1 = new CWeightSheets();
                            cWeightSheets1.setId(cWeightSheets2.getId());
                            cWeightSheets1.setWeishtDeduction(BigDecimal.valueOf(1));
                            cWeightSheets1.setWeishtMoney(monery);
                            cWeightSheets1.setWeishtMarketPrice(marketPrice);
                            cWeightSheets1.setWeightSpecialPrice(specialPrice);
                            cWeightSheets1.setWeishtPrice(price);
                            iCWeightSheetsService.updateById(cWeightSheets1);
                            continue;
                        }
//                        计算金额
                        if (monery.compareTo(BigDecimal.ZERO) >= 0) {
                            Map<String, Object> map = executeDeduction(cWeightSheets2.getWeishtCo(), cWeightSheets2.getWeishtChiCo(), cCompanys.getId(), monery, cWeightSheets2.getDataFrom());
                            if (map.get("code") != null && map.get("code").equals("0")) {
                                CWeightSheets cWeightSheets1 = new CWeightSheets();
                                cWeightSheets1.setId(cWeightSheets2.getId());
                                cWeightSheets1.setWeishtDeduction(BigDecimal.valueOf(1));
                                cWeightSheets1.setWeishtMoney(monery);
                                cWeightSheets1.setWeishtMarketPrice(marketPrice);
                                cWeightSheets1.setWeightSpecialPrice(specialPrice);
                                cWeightSheets1.setWeishtPrice(price);
                                iCWeightSheetsService.updateById(cWeightSheets1);
                            } else {
                                log.error("单号【" + cWeightSheets2.getWeishtSheetno() + "】" + "扣款失败，执行扣款失败" + map.get("msg"));
                            }
                        }
                    } else {
                        log.error("单号【" + cWeightSheets2.getWeishtSheetno() + "】" + "扣款失败，未找到收款单位");
                    }
//                    如果拿不到就先不要扣款

                }
                else {
                    log.error("单号【" + cWeightSheets2.getWeishtSheetno() + "】" + "扣款失败，未找到收款单位");
                }
            }
        }
    }



    //                   拿到市场价
    public Map<String, Object> getPrice(String productId, String co, String chiCo,
                                        LocalDateTime fullTime,String plantId) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 1);
        QueryWrapper<CPdtsAuth> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PDTSAUTH_PDT", productId);
        queryWrapper.eq("PDTSAUTH_CO", co);
        queryWrapper.eq("PDTSAUTH_CHICO", chiCo);
        queryWrapper.eq("DATA_FROM", plantId);
        queryWrapper.eq("PDTSAUTH_DELETED", 0);
        CPdtsAuth cPdtsAuth = icPdtsAuthService.getOne(queryWrapper);
        if (cPdtsAuth == null) {
//            没有查到品种授权信息
            map.put("code", 1);
            return map;
        }
        if (cPdtsAuth.getPdtsauthPrice() == null) {
            //                没有市场价
            map.put("code", 2);
            return map;
        }
//        正常拿到市场价
        map.put("code", 0);
        map.put("price", cPdtsAuth.getPdtsauthPrice());
// 获取预调价开始时间和结束时间
        LocalDateTime pdtsauthPreStartTime = cPdtsAuth.getPdtsauthPreStartTime();
        LocalDateTime pdtsauthPreStartTime2 = cPdtsAuth.getPdtsauthPreStartTime2();

// 获取预调价价格
        BigDecimal pdtsauthPrePrice = cPdtsAuth.getPdtsauthPrePrice();
        BigDecimal pdtsauthPrePrice2 = cPdtsAuth.getPdtsauthPrePrice2();

// 检查是否有有效的预调价时间段
        if (pdtsauthPreStartTime != null && pdtsauthPrePrice != null && (fullTime.isAfter(pdtsauthPreStartTime) || fullTime.isEqual(pdtsauthPreStartTime))) {
            // 如果 pdtsauthPreStartTime2 也有效，比较两个时间点
            if (pdtsauthPreStartTime2 != null && pdtsauthPrePrice2 != null && (fullTime.isAfter(pdtsauthPreStartTime2) || fullTime.isEqual(pdtsauthPreStartTime2))) {
                // 确定哪个预调价应该被应用
                if (pdtsauthPreStartTime2.isAfter(pdtsauthPreStartTime) || pdtsauthPreStartTime2.isEqual(pdtsauthPreStartTime)) {
                    map.put("price", pdtsauthPrePrice2);
                    // 顺带更新价格
                    if (pdtsauthPrePrice2.compareTo(cPdtsAuth.getPdtsauthPrice()) != 0) {
                        CPdtsAuth cPdtsAuth1 = new CPdtsAuth();
                        cPdtsAuth1.setId(cPdtsAuth.getId());
                        cPdtsAuth1.setPdtsauthPrice(pdtsauthPrePrice2);
                        cPdtsAuth1.setPdtsauthOprtr(cPdtsAuth.getPdtsauthPreOprtr2());
                        cPdtsAuth1.setPdtsauthTime(cPdtsAuth.getPdtsauthPreTime2());
                        icPdtsAuthService.updateById(cPdtsAuth1);
                    }
                } else {
                    map.put("price", pdtsauthPrePrice);
                    // 顺带更新价格
                    if (pdtsauthPrePrice.compareTo(cPdtsAuth.getPdtsauthPrice()) != 0) {
                        CPdtsAuth cPdtsAuth1 = new CPdtsAuth();
                        cPdtsAuth1.setId(cPdtsAuth.getId());
                        cPdtsAuth1.setPdtsauthPrice(pdtsauthPrePrice);
                        cPdtsAuth1.setPdtsauthOprtr(cPdtsAuth.getPdtsauthPreOprtr());
                        cPdtsAuth1.setPdtsauthTime(cPdtsAuth.getPdtsauthPreTime());
                        icPdtsAuthService.updateById(cPdtsAuth1);
                    }
                }
            } else {
                // 只有 pdtsauthPreStartTime 有效
                map.put("price", pdtsauthPrePrice);
                // 顺带更新价格
                if (pdtsauthPrePrice.compareTo(cPdtsAuth.getPdtsauthPrice()) != 0) {
                    CPdtsAuth cPdtsAuth1 = new CPdtsAuth();
                    cPdtsAuth1.setId(cPdtsAuth.getId());
                    cPdtsAuth1.setPdtsauthPrice(pdtsauthPrePrice);
                    cPdtsAuth1.setPdtsauthOprtr(cPdtsAuth.getPdtsauthPreOprtr());
                    cPdtsAuth1.setPdtsauthTime(cPdtsAuth.getPdtsauthPreTime());
                    icPdtsAuthService.updateById(cPdtsAuth1);
                }
            }
        } else if (pdtsauthPreStartTime2 != null && pdtsauthPrePrice2 != null && (fullTime.isAfter(pdtsauthPreStartTime2) || fullTime.isEqual(pdtsauthPreStartTime2))) {
            // 只有 pdtsauthPreStartTime2 有效
            map.put("price", pdtsauthPrePrice2);
            // 顺带更新价格
            if (pdtsauthPrePrice2.compareTo(cPdtsAuth.getPdtsauthPrice()) != 0) {
                CPdtsAuth cPdtsAuth1 = new CPdtsAuth();
                cPdtsAuth1.setId(cPdtsAuth.getId());
                cPdtsAuth1.setPdtsauthPrice(pdtsauthPrePrice2);
                cPdtsAuth1.setPdtsauthOprtr(cPdtsAuth.getPdtsauthPreOprtr2());
                cPdtsAuth1.setPdtsauthTime(cPdtsAuth.getPdtsauthPreTime2());
                icPdtsAuthService.updateById(cPdtsAuth1);
            }
        }
        return map;
    }
//                      执行扣款     Execute deduction
//    ORDETAIL_SUB_ID
    public Map<String,Object> executeDeduction(String co,String chiCo,String subId,BigDecimal monery,String plantId){
        Map<String,Object> map = new HashMap<>();
//        先查一下他的余额账户
        QueryWrapper<COrderDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ORDETAIL_CO",co);
        queryWrapper.eq("ORDETAIL_CHICO", chiCo);
        queryWrapper.eq("ORDETAIL_SUB_ID", subId);
        queryWrapper.eq("DATA_FROM", plantId);
        queryWrapper.ne("ORDETAIL_DELETED", 1);
        COrderDetail cOrderDetail = iCOrderDetailService.getOne(queryWrapper);
        if (cOrderDetail == null) {
            map.put("code", "1");
            map.put("msg", "未找到账户");
            return map;
        }
//        if (cOrderDetail.getOrdetailRemainNum().compareTo(monery) < 0) {
//            map.put("code", "2");
//            map.put("msg", "账户余额不足，扣款失败");
//            return map;
//        }
//updateOrderDetailExecuteDeduction      cOrderDetailMapper
        cOrderDetailMapper.updateOrderDetailExecuteDeduction(monery,cOrderDetail.getId());
        map.put("code", "0");
        map.put("msg", "扣款成功");
        return map;
    }




    //    授权品种
//    public void handleProduct() {
////      查出所有粉煤灰单位
//        QueryWrapper<CCompanys> queryWrapper = new QueryWrapper<>();
//        queryWrapper.like("CPY_ADDR", "粉煤灰");
//        queryWrapper.eq("CPY_DELETED", 0);
//
//        queryWrapper.ne("CPY_CO", "鲁南中联水泥有限公司");
//        queryWrapper.ne("CPY_CO", "东鲁平环保建材有限公司");
//        queryWrapper.ne("CPY_CO", "浙江北灰南运供应链有限公司");
//        List<CCompanys> cCompanys = iCCompanysService.list(queryWrapper);
//        List<String> pdtTypes = Arrays.asList(
//                "二级灰",
//                "加湿灰",
//                "原灰",
//                "大袋灰",
//                "粗灰",
//                "细灰",
//                "钢板仓原灰"
//        );
//
//        for (String pdtType : pdtTypes) {
//            for (CCompanys cCompany : cCompanys) {
//                CPdtsAuth cpdtsAuth = new CPdtsAuth();
//                cpdtsAuth.setPdtsauthPdt(pdtType); // 使用当前品种类型
//                cpdtsAuth.setPdtsauthCo(cCompany.getCpyCo());
//                cpdtsAuth.setPdtsauthChico(cCompany.getCpyChico());
//                cpdtsAuth.setPdtsauthPrice(BigDecimal.valueOf(0));
//                cpdtsAuth.setPdtsauthOprtr("管理员");
//                cpdtsAuth.setPdtsauthReason("授权");
//                cpdtsAuth.setPdtsauthTime(LocalDateTime.now());
//                cpdtsAuth.setPdtsauthLock(0);
//                cpdtsAuth.setPdtsauthDeleted(0);
//                cpdtsAuth.setDataFrom("huadianzouxian");
//                icPdtsAuthService.save(cpdtsAuth);
//            }
//        }
//    }

//    搭配销售方法
public String getSellMethod(String ashgateId) {

    // 创建查询条件
    QueryWrapper<TAshGateCollocation> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("ASH_GATE_ID1", ashgateId);
    queryWrapper.eq("ENABLE_FLAG", 1);

    // 获取符合条件的TAshGateCollocation列表
    List<TAshGateCollocation> tAshGateCollocations = iTAshGateCollocationService.list(queryWrapper);

    if (tAshGateCollocations.isEmpty()) {
        return "";
    }

    // 返回搭配销售库的名字
    List<String> sellMethod = new ArrayList<>();

    // 确保最多只处理两个元素
    int limit = Math.min(2, tAshGateCollocations.size());

    for (int i = 0; i < limit; i++) {
        TAshGateCollocation collocation = tAshGateCollocations.get(i);
        QueryWrapper<CAshGateVideoBind> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("ID", collocation.getAshGateId2());
        CAshGateVideoBind cAshGateVideoBind = iCAshGateVideoBindService.getOne(queryWrapper1);
        if (cAshGateVideoBind != null) { // 确保查询结果不为空
            sellMethod.add(cAshGateVideoBind.getAshgateName());
        }
    }

    // 将sellMethod列表转换为一个用逗号分隔的字符串
    return String.join(",", sellMethod);
}
//在没有开启计划的情况下，储备库炉渣是一天公司一天计划,如果前一天没有就一直往前找，找到30天为止
public void getSellMethod1(CWeightSheets cWeightSheets, String productsInfo, String plantId, LocalDateTime now) {
    if (productsInfo.equals("储备库炉渣") || productsInfo.equals("c9cf42874ddc446891ec936c5bf67386")) {
        QueryWrapper<SysDic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("DIC_KEY", "queueControl_chubkuluzha_plan");
        queryWrapper.eq("DATA_FROM", plantId);
        SysDic one = sysDicService.getOne(queryWrapper);
        if (one != null && one.getDicVal().equals("0")) {
            int maxDaysToSearch = 30; // 设置最大的查询天数
            for (int i = 1; i <= maxDaysToSearch; i++) {
                LocalDateTime startOfDay = now.minusDays(i).with(LocalTime.MIN);
                LocalDateTime endOfDay = now.minusDays(i).with(LocalTime.MAX);
                QueryWrapper<CWeightSheets> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("WEISHT_PRODUCT", "储备库炉渣")
                        .ge("WEISHT_FULL_TM", startOfDay)
                        .lt("WEISHT_FULL_TM", endOfDay)
                        .eq("WEISHT_DELETED", 0)
                        .eq("DATA_FROM", plantId);
                List<CWeightSheets> list = iCWeightSheetsService.list(queryWrapper1);
                if (list.size() > 0) {
                    CWeightSheets cWeightSheets1 = list.get(0);
                    if (cWeightSheets1.getWeishtCoSupply() != null) {
                        CWeightSheets cWeightSheets2 = new CWeightSheets();
                        cWeightSheets2.setId(cWeightSheets.getId());
                        cWeightSheets2.setWeishtCoSupply(cWeightSheets1.getWeishtCoSupply().equals("公司") ? "电厂" : "公司");
                        cWeightSheets2.setWeishtCoSupplyChi("，"); // 注意这里的逗号可能是中文输入错误，通常应为英文逗号或根据实际需求设置
                        iCWeightSheetsService.updateById(cWeightSheets2);
                    }
                    break; // 找到后立即退出循环
                }
            }
        }
    }
}

//每天0点执行，打包销售的量如果第二天还有的话，也就是0点在结束时间内，那就重置他的量TSpecialPrice里的剩余量
      public void resetPackageSelling() {
          LocalDateTime now = LocalDateTime.now();
//          因为是0点执行，等于是第二天了
          LocalDateTime endOfDay = now.with(LocalTime.MIN);
          QueryWrapper<TSpecialPrice> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq("PRICE_TYPE_ID", "0705df3110c911ef823f00ff8a757bed");
          queryWrapper.ge("END_TIME", endOfDay);
          List<TSpecialPrice> list = itSpecialPriceService.list(queryWrapper);
          if (list != null) {
              if (list.size() > 0) {
                  for (TSpecialPrice tSpecialPrice : list) {
                      TSpecialPrice tSpecialPrice1 = new TSpecialPrice();
                      tSpecialPrice1.setId(tSpecialPrice.getId());
                      tSpecialPrice1.setResidueNum(tSpecialPrice.getNum());
                      itSpecialPriceService.updateById(tSpecialPrice1);
                  }
              }
          }
      }

    ////        这里还要排队石膏渣里有没有不需要排计划的品种，true需要排计划
    public boolean getNoNeedPlan(String productsName, String plantId) {
//        先判断储备库炉渣是否要排计划c9cf42874ddc446891ec936c5bf67386，储备库炉渣是有计划开关的
        if (productsName.equals("储备库炉渣") ) {
            QueryWrapper<SysDic> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("DIC_KEY", "queueControl_chubkuluzha_plan");
            queryWrapper.eq("DATA_FROM", plantId);
            SysDic one = sysDicService.getOne(queryWrapper);
            return one.getDicVal().equals("1");
        }
//            应急炉渣不需要排计划
        if (productsName.equals("应急炉渣")) {
            return false;
        }
        //            转倒炉渣不需要排计划
        if (productsName.equals("转倒炉渣")) {
            return false;
        }
        return true;
    }
}

